// 引入必要的命名空间
using UniversalAdmin.Application.DTOs; // 引入数据传输对象定义
using UniversalAdmin.Domain.Entities; // 引入领域实体定义
using UniversalAdmin.Domain.Repositories; // 引入仓储接口定义
using UniversalAdmin.Shared.Enums; // 引入共享枚举定义

// 定义服务层的命名空间
namespace UniversalAdmin.Application.Services;

// 实现文章服务接口
public class ArticleService : IArticleService
{
    // 注入文章仓储接口
    private readonly IArticleRepository _articleRepository;
    // 注入用户仓储接口
    private readonly IUserRepository _userRepository;
    // 注入文章分类仓储接口
    private readonly IArticleCategoryRepository _categoryRepository;

    // 构造函数，依赖注入三个仓储接口
    public ArticleService(IArticleRepository articleRepository, IUserRepository userRepository, IArticleCategoryRepository categoryRepository)
    {
        _articleRepository = articleRepository;
        _userRepository = userRepository;
        _categoryRepository = categoryRepository;
    }

    // 分页获取文章列表
    public async Task<PagedResultDto<ArticleDto>> GetArticlesAsync(int page = 1, int pageSize = 10, ArticleStatus? status = null, Guid? categoryId = null, string? keyword = null)
    {
        // 调用仓储层获取分页文章列表和总数
        var (articles, totalCount) = await _articleRepository.GetPagedAsync(page, pageSize, status, categoryId, keyword);
        // 将文章实体映射为DTO
        var articleDtos = await MapToDtosAsync(articles);

        // 返回分页结果
        return new PagedResultDto<ArticleDto>
        {
            Items = articleDtos.ToList(),
            TotalCount = totalCount,
            Page = page,
            PageSize = pageSize
        };
    }

    // 根据ID获取单个文章
    public async Task<ArticleDto?> GetArticleByIdAsync(Guid id)
    {
        // 调用仓储层根据ID获取文章
        var article = await _articleRepository.GetByIdAsync(id);
        // 如果文章不存在，返回null
        if (article == null) return null;

        // 将文章实体映射为DTO并返回
        var articleDtos = await MapToDtosAsync(new[] { article });
        return articleDtos.FirstOrDefault();
    }

    // 创建新文章
    public async Task<ArticleDto> CreateArticleAsync(CreateArticleDto dto, Guid authorId)
    {
        // 根据DTO创建文章实体
        var article = new Article
        {
            Title = dto.Title,
            Content = dto.Content,
            Summary = dto.Summary,
            CoverImage = dto.CoverImage,
            Status = dto.Status,
            CategoryId = dto.CategoryId,
            Tags = dto.Tags,
            AuthorId = authorId,
            CreatedAt = DateTime.UtcNow
        };

        // 如果文章状态为已发布，设置发布时间
        if (dto.Status == ArticleStatus.Published)
        {
            article.PublishedAt = DateTime.UtcNow;
        }

        // 调用仓储层添加文章
        var createdArticle = await _articleRepository.AddAsync(article);
        // 将新创建的文章映射为DTO并返回
        var articleDtos = await MapToDtosAsync(new[] { createdArticle });
        return articleDtos.First();
    }

    // 更新文章
    public async Task<ArticleDto?> UpdateArticleAsync(Guid id, UpdateArticleDto dto)
    {
        // 调用仓储层根据ID获取文章
        var article = await _articleRepository.GetByIdAsync(id);
        // 如果文章不存在，返回null
        if (article == null) return null;

        // 更新文章属性
        article.Title = dto.Title;
        article.Content = dto.Content;
        article.Summary = dto.Summary;
        article.CoverImage = dto.CoverImage;
        article.Status = dto.Status;
        article.CategoryId = dto.CategoryId;
        article.Tags = dto.Tags;
        article.UpdatedAt = DateTime.UtcNow;

        // 如果状态从非发布变为发布，设置发布时间
        if (dto.Status == ArticleStatus.Published && article.PublishedAt == null)
        {
            article.PublishedAt = DateTime.UtcNow;
        }

        // 调用仓储层更新文章
        await _articleRepository.UpdateAsync(article);
        // 将更新后的文章映射为DTO并返回
        var articleDtos = await MapToDtosAsync(new[] { article });
        return articleDtos.First();
    }

    // 删除文章
    public async Task<bool> DeleteArticleAsync(Guid id)
    {
        // 调用仓储层根据ID获取文章
        var article = await _articleRepository.GetByIdAsync(id);
        // 如果文章不存在，返回false
        if (article == null) return false;

        // 调用仓储层删除文章
        await _articleRepository.DeleteAsync(article);
        // 返回删除成功标志
        return true;
    }

    // 更新文章状态
    public async Task<bool> UpdateArticleStatusAsync(Guid id, ArticleStatus status)
    {
        // 调用仓储层根据ID获取文章
        var article = await _articleRepository.GetByIdAsync(id);
        // 如果文章不存在，返回false
        if (article == null) return false;

        // 更新文章状态
        article.Status = status;
        // 如果状态为已发布且未设置发布时间，设置发布时间
        if (status == ArticleStatus.Published && article.PublishedAt == null)
        {
            article.PublishedAt = DateTime.UtcNow;
        }
        article.UpdatedAt = DateTime.UtcNow;

        // 调用仓储层更新文章
        await _articleRepository.UpdateAsync(article);
        // 返回更新成功标志
        return true;
    }

    // 增加文章浏览量
    public async Task<bool> IncrementViewCountAsync(Guid id)
    {
        // 调用仓储层根据ID获取文章
        var article = await _articleRepository.GetByIdAsync(id);
        // 如果文章不存在，返回false
        if (article == null) return false;

        // 增加文章浏览量
        article.ViewCount++;
        // 调用仓储层更新文章
        await _articleRepository.UpdateAsync(article);
        // 返回更新成功标志
        return true;
    }

    // 根据分类ID获取文章列表
    public async Task<IEnumerable<ArticleDto>> GetArticlesByCategoryAsync(Guid categoryId, int page = 1, int pageSize = 10)
    {
        // 调用仓储层根据分类ID获取文章列表
        var articles = await _articleRepository.GetByCategoryAsync(categoryId, page, pageSize);
        // 将文章实体映射为DTO并返回
        return await MapToDtosAsync(articles);
    }

    // 根据作者ID获取文章列表
    public async Task<IEnumerable<ArticleDto>> GetArticlesByAuthorAsync(Guid authorId, int page = 1, int pageSize = 10)
    {
        // 调用仓储层根据作者ID获取文章列表
        var articles = await _articleRepository.GetByAuthorAsync(authorId, page, pageSize);
        // 将文章实体映射为DTO并返回
        return await MapToDtosAsync(articles);
    }

    // 将文章实体映射为DTO
    private async Task<IEnumerable<ArticleDto>> MapToDtosAsync(IEnumerable<Article> articles)
    {
        // 提取文章ID列表
        var articleIds = articles.Select(a => a.Id).ToList();
        // 提取作者ID列表（去重）
        var authorIds = articles.Select(a => a.AuthorId).Distinct().ToList();
        // 提取分类ID列表（去重）
        var categoryIds = articles.Select(a => a.CategoryId).Distinct().ToList();

        // 调用仓储层批量获取作者和分类信息
        var authors = await _userRepository.GetByIdsAsync(authorIds);
        var categories = await _categoryRepository.GetByIdsAsync(categoryIds);

        // 构建作者和分类的字典，便于快速查找
        var authorDict = authors.ToDictionary(u => u.Id, u => u.UserName);
        var categoryDict = categories.ToDictionary(c => c.Id, c => c.Name);

        // 将文章实体映射为DTO
        return articles.Select(article => new ArticleDto
        {
            Id = article.Id,
            Title = article.Title,
            Content = article.Content,
            Summary = article.Summary ?? "",
            CoverImage = article.CoverImage,
            Status = article.Status,
            CategoryId = article.CategoryId,
            CategoryName = categoryDict.GetValueOrDefault(article.CategoryId, string.Empty),
            Tags = article.Tags,
            ViewCount = article.ViewCount,
            AuthorId = article.AuthorId,
            AuthorName = authorDict.GetValueOrDefault(article.AuthorId, string.Empty) ?? "",
            PublishedAt = article.PublishedAt,
            CreatedAt = article.CreatedAt,
            UpdatedAt = article.UpdatedAt
        });
    }
}